package com.aaa.sso.config;

import com.aaa.common.constants.BusinessConstant;
import com.aaa.sso.util.CustomModularRealmAuthenticator;
import com.aaa.sso.util.MemberRealm;
import com.aaa.sso.util.UserRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Xiujie Yu
 * @Date 2021-01-21
 * @Time 16:10
 */
@Configuration
public class ShiroConfig {

    /**
     * 功能描述:实例化ShiroFilterFactoryBean
     *
     * @return org.apache.shiro.spring.web.ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //LinkedHashMap可以按照put的先后顺序 存放值
        Map<String, String> chainDefinitionMap = new LinkedHashMap<>();
        //所有请求直接放行
        chainDefinitionMap.put("/**", "anon");
        //确定拦截或者放行的路径
        shiroFilterFactoryBean.setFilterChainDefinitionMap(chainDefinitionMap);
        //配置SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        return shiroFilterFactoryBean;
    }

    /**
     * 功能描述:安全管理器 是shiro的核心组件， 所有的认证和授权都是它来执行
     *
     * @return java.lang.SecurityManager
     */
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //设置认证器
        defaultWebSecurityManager.setAuthenticator(customModularRealmAuthenticator());
        //定义一个realm对象
        List<Realm> realmList = new ArrayList<>();
        realmList.add(memberRealm());
        realmList.add(userRealm());
        defaultWebSecurityManager.setRealms(realmList);
        return defaultWebSecurityManager;
    }

    @Bean
    public CustomModularRealmAuthenticator customModularRealmAuthenticator() {
        CustomModularRealmAuthenticator customModularRealmAuthenticator = new CustomModularRealmAuthenticator();
        //双realm 只要一个realm认证成功就成功
        customModularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return customModularRealmAuthenticator;
    }

    /**
     * 功能描述:会员Realm
     *
     * @return com.aaa.sso.util.MemberRealm
     */
    @Bean
    public MemberRealm memberRealm() {
        MemberRealm memberRealm = new MemberRealm();
        //验证匹配器 设置加密算法及hash次数
        memberRealm.setCredentialsMatcher(credentialsMatcher());
        return memberRealm;
    }

    /**
     * 功能描述:后台用户Realm
     *
     * @return com.aaa.sso.util.UserRealm
     */
    @Bean
    public UserRealm userRealm() {
        UserRealm userRealm = new UserRealm();
        userRealm.setCredentialsMatcher(credentialsMatcher());
        return userRealm;
    }

    /**
     * 功能描述:实例化验证匹配器 设置加密算法名称及hash次数
     *
     * @return org.apache.shiro.authc.credential.CredentialsMatcher
     */
    @Bean
    public CredentialsMatcher credentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();

        credentialsMatcher.setHashAlgorithmName(BusinessConstant.CredentialsPassword.ALGORITHM_NAME);

        credentialsMatcher.setHashIterations(BusinessConstant.CredentialsPassword.HASH_ITERATIONS);
        return credentialsMatcher;
    }
}
